﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
//-----------------------------------
using Controller;
using BusinessModel;
using ManageStore.Config;
using System.Data.SqlClient;
using ManageStore.Common;
using Controller.DataProvider;
using BaseUtilities;
using ManageStore.IViews;

namespace ManageStore.Forms
{
    public partial class FrmProductType : BaseForm, IProductTypeView
    {
        public FrmProductType()
        {
            InitializeComponent();

            lblParentId.ForeColor = lblParentName.ForeColor = lblProductTypeId.ForeColor = lblProductTypeId.BackColor;

            ProductTypeCtr = new ProductTypeCtr(this);
            productTypeCtrBindingSource.DataSource = ProductTypeCtr;
            EvtNew += ProductTypeCtr.MtdNew;
            EvtEdit += ProductTypeCtr.MtdEdit;
            EvtDelete += ProductTypeCtr.MtdDelete;
            EvtSave += ProductTypeCtr.MtdSave;
            EvtGetAllChilds += ProductTypeCtr.MtdGetAllChilds;
        }
        private void FrmProductType_Load(object sender, EventArgs e)
        {
            dgvProductType.AutoGenerateColumns = false;
            dgvProductType.DataSource = ProductTypeCtr.LstProductType;
            CreateTreeview();
        }

        #region Properties
        // ProductTypeCtr.
        private ProductTypeCtr _ProductTypeCtr;
        public ProductTypeCtr ProductTypeCtr
        {
            get { return _ProductTypeCtr; }
            set { _ProductTypeCtr = value; }
        }
        //----------------------------------------
        public event EventHandler EvtSaved;
        public bool IsDialog { get; set; }
        public string ProductTypeName
        {
            get { return txtTypeName.Text; }
            set { txtTypeName.Text = value; }
        }
        public bool IsLoaded { get; set; }
        #endregion Properties

        #region Private Methods
        //----------------------------------------
        private void NewProductType()
        {
            //_ProductTypeCtr.ProductType = new ProductType();
            //ControlBinding();
            //dgvProductType.ClearSelection();
        }
        //----------------------------------------
        private void CreateTreeview()
        {
            TreeNode oTreeNode = new TreeNode();
            oTreeNode.Name = "0";
            oTreeNode.Text = "Gốc";
            trvParentType.Nodes.Clear();
            trvParentType.Nodes.Add(oTreeNode);
            OnGetAllChilds((result) =>
                {
                    IList<ProductType> lstPro = result as IList<ProductType>;
                    CreateSubNode(oTreeNode, lstPro);
                    trvParentType.SelectedNode = oTreeNode;
                    oTreeNode.Expand();
                });
        }
        //----------------------------------------
        private void CreateSubNode(TreeNode pTreeNode, IList<ProductType> pLstProductType)
        {
            pLstProductType.ToList().ForEach((item) =>
                {
                    TreeNode _TreeNode = new TreeNode();
                    _TreeNode.Name = item.Id.ToString();
                    _TreeNode.Text = item.Name;
                    pTreeNode.Nodes.Add(_TreeNode);
                    OnGetAllChilds((childs) =>
                    {
                        IList<ProductType> lstPro = childs as IList<ProductType>;
                        CreateSubNode(_TreeNode, lstPro);
                    }, item.Id);
                    //IList<ProductType> lstPro = _ProductTypeCtr.GetAllChilds(item.Id).ToResult<IList<ProductType>>();
                });
        }
        //----------------------------------------
        public void ReloadData()
        {
            //dgvProductType.DataSource = null;
            dgvProductType.DataSource = ProductTypeCtr.LstProductType;
        }

        public event ActionInvoke EvtGetAllChilds;
        public void OnGetAllChilds(Action<object> pAction, params object[] pParams)
        {
            if (EvtGetAllChilds != null)
                EvtGetAllChilds(pAction, pParams);
        }
        #endregion Private Methods

        // Before.
        //----------------------------------------
        public override bool BeforeHandler(string pEventName, params object[] pParams)
        {
            bool result = true;
            int iProductTypeId = 0;
            int.TryParse(lblProductTypeId.Text, out iProductTypeId);
            switch (pEventName)
            {
                case "EvtNew":
                    dgvProductType.ClearSelection();
                    errorProvider1.Clear();
                    break;
                case "EvtEdit":
                    break;
                case "EvtDelete":
                    if (iProductTypeId > 0)
                    {
                        if (MessageBox.Show("Bạn có chắc muốn xóa không?", "Cảnh báo", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.OK)
                        {
                            OnGetAllChilds((childs) =>
                            {
                                IList<ProductType> lstPro = childs as IList<ProductType>;
                                if (lstPro.Count > 0)
                                {
                                    MessageBox.Show(txtTypeName.Text + " không thể xóa. Vì nó có loại hàng con", "Lỗi");
                                    result = false;
                                }
                            }, iProductTypeId);
                        }
                        else
                        {
                            result = false;
                        }
                    }
                    break;
                case "EvtSave":
                    if (iProductTypeId > 0)
                    {
                        TreeNode oTreeNode = trvParentType.Nodes.Find(iProductTypeId.ToString(), true).FirstOrDefault();
                        if (oTreeNode == trvParentType.SelectedNode)
                        {
                            MessageBox.Show("Không thể chọn chính nó", "Lỗi");
                            result = false;
                        }
                    }
                    break;
            }
            return result;
        }
        // Error.
        //----------------------------------------
        public override bool ErrorHandler(string pEventName, params object[] pParams)
        {
            bool result = true;
            switch (pEventName)
            {
                case "EvtDelete":
                    if (pParams.Count() == 1)
                    {
                        ResultModel oResultModel = pParams[0] as ResultModel;
                        if (oResultModel.ErrorNumber == ManageStoreConfig.ErrorForeignKey)
                        {
                            MessageBox.Show("Loại hàng này đã được dùng. Không thể xóa được!", "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    break;
                case "EvtSave":
                    string sError = "Không thể lưu được.";
                    if (pParams.Count() == 1)
                    {
                        Dictionary<string, Dictionary<string, string>> lstError = pParams[0] as Dictionary<string, Dictionary<string, string>>;
                        if (lstError != null && lstError.Count > 0)
                        {
                            sError = "Dữ liệu nhập vào không hợp lệ.";
                        }
                    }
                    MessageBox.Show(sError, "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
            }
            return result;
        }
        // Completed.
        //----------------------------------------
        public override bool CompletedHandler(string pEventName, params object[] pParams)
        {
            bool result = true;
            switch (pEventName)
            {
                case "EvtNew":
                    txtTypeCode.Focus();
                    break;
                case "EvtEdit":
                    MtdUpdateTreeView(CommandStatus.Edit);
                    txtTypeCode.SelectAll();
                    txtTypeCode.Focus();
                    errorProvider1.Clear();
                    break;
                case "EvtSave":
                    int iProductId = 0;
                    int.TryParse(pParams[0].ToString(), out iProductId);
                    if (EvtSaved != null)
                    {
                        EvtSaved(iProductId, null);
                        if (IsDialog)
                            this.Close();
                    }
                    if (pParams.Count() == 1)
                        lblProductTypeId.Text = pParams[0].ToString();
                    MtdUpdateTreeView(CommandStatus.Save);
                    OnEvtNew();
                    break;
                case "EvtDelete":
                    MtdUpdateTreeView(CommandStatus.Delete);
                    OnEvtNew();
                    break;
            }
            return result;
        }
        // Validation.
        //----------------------------------------
        public override bool ValidationHandler(string pColumnName, params object[] pParams)
        {
            bool result = true;
            if (!string.IsNullOrWhiteSpace(pColumnName))
            {
                // Get Error control.
                Control ctl = null;
                switch (pColumnName)
                {
                    case "ProductTypeCode":
                        ctl = txtTypeCode;
                        break;
                    case "ProductTypeName":
                        ctl = txtTypeName;
                        break;
                }
                // Set Control Error.
                if (ctl != null)
                {
                    if (pParams.Count() == 1 && !string.IsNullOrEmpty(pParams[0].ToString()))
                        errorProvider1.SetError(ctl, pParams[0].ToString());
                    else
                        errorProvider1.SetError(ctl, null);
                }
            }
            return result;
        }

        private void MtdUpdateTreeView(CommandStatus pCommandStatus)
        {
            TreeNode oTreeNode = null;
            switch (pCommandStatus)
            {
                // Delete.
                case CommandStatus.Delete:
                    oTreeNode = trvParentType.Nodes.Find(lblProductTypeId.Text, true).FirstOrDefault();
                    oTreeNode.Remove();
                    break;
                // Edit.
                case CommandStatus.Edit:
                    int iParentId = 0;
                    int.TryParse(lblParentId.Text, out iParentId);
                    trvParentType.CollapseAll();
                    trvParentType.SelectedNode = trvParentType.Nodes.Find(iParentId.ToString(), true).FirstOrDefault();
                    trvParentType.SelectedNode.Expand();
                    break;
                // Save.
                case CommandStatus.Save:
                    // New.
                    if (trvParentType.SelectedNode == null)
                    {
                        trvParentType.SelectedNode = trvParentType.Nodes.Find("0", true).FirstOrDefault();
                    }
                    int iProdcutTypeId = 0;
                    int.TryParse(lblProductTypeId.Text, out iProdcutTypeId);
                    oTreeNode = trvParentType.Nodes.Find(iProdcutTypeId.ToString(), true).FirstOrDefault();
                    if (oTreeNode == null)
                    {
                        oTreeNode = new TreeNode();
                        trvParentType.SelectedNode.Nodes.Add(oTreeNode);
                    }
                    if (oTreeNode.Parent != trvParentType.SelectedNode)
                    {
                        oTreeNode.Remove();
                        trvParentType.SelectedNode.Nodes.Add(oTreeNode);
                    }
                    oTreeNode.Name = lblProductTypeId.Text;
                    oTreeNode.Text = txtTypeName.Text; 
                    break;
            }
        }
        #region Dotnet Methods
        //----------------------------------------
        private void btnAdd_Click(object sender, EventArgs e)
        {
            OnEvtNew();
        }
        //----------------------------------------
        private void btnSave_Click(object sender, EventArgs e)
        {
            OnEvtSave();
        }
        //----------------------------------------
        private void btnDelete_Click(object sender, EventArgs e)
        {
            OnEvtDelete();
        }
        //----------------------------------------
        private void btnQuit_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        //----------------------------------------
        private void dgvProductType_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            dgvProductType.ClearSelection();
            //OnEvtNew();
        }
        //----------------------------------------
        private void dgvProductType_SelectionChanged(object sender, EventArgs e)
        {
            if (IsLoaded && dgvProductType.SelectedRows.Count > 0)
            {
                OnEvtEdit(dgvProductType.SelectedRows[0].DataBoundItem);
            }
        }
        //----------------------------------------
        private void FrmProductType_Activated(object sender, EventArgs e)
        {
            if (!IsLoaded)
            {
                IsLoaded = true;
            }
        }
        //----------------------------------------
        private void lblTypeId_TextChanged(object sender, EventArgs e)
        {
            //btnDelete.Enabled = !string.IsNullOrWhiteSpace(lblTypeId.Text) && Convert.ToInt32(lblTypeId.Text) > 0;
        }
        //----------------------------------------
        private void trvParentType_AfterSelect(object sender, TreeViewEventArgs e)
        {
            lblParentId.Text = e.Node.Name;
            if (e.Node.Name == "0")
            {
                lblParentName.Text = null;
            }
            else
            {
                lblParentName.Text = e.Node.Text;
            }
        }
        #endregion Dotnet Methods
    }
}
